package com.ys.day30.p1回顾升级;

import org.junit.Test;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述:
 *
 * @author CodeYang
 * @version 2021/1/12 19:43
 */
public class TestCase {

    /**
     * p1: 测试 通过全类名创建对象
     */
    @Test
    public void Test01(){
        try {
            Student object = ReflectUtils.creteObject("com.ys.day30.p1回顾升级.Student");
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * p2: 测试 通过字节码对象 Class对象创建对象
     */
    @Test
    public void Test02(){
        try {

            Student object = ReflectUtils.creteObject(Student.class);
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * p3: 测试 通过 class全类名 调用有参的构造方法创建对象
     *
     */
    @Test
    public void Test03(){
        try {
            // 1: 参数类型列表
            Class<?>[] params = {int.class,String.class,String.class};
            // 2: 值列表
            Object[] values = {110,"xw","love"};
            Student object = ReflectUtils.creteObject("com.ys.day30.p1回顾升级.Student",values,params);
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * p4: 测试 通过 class对象 调用有参的构造方法创建对象
     *
     */
    @Test
    public void Test04(){
        try {
            // 1: 参数类型列表
            Class<?>[] params = {int.class,String.class,String.class};
            // 2: 值列表
            Object[] values = {110,"xw8855","love111"};
            Student object = ReflectUtils.creteObject(Student.class,values,params);
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * p5: 测试 通过对象反射+方法名调用对象的无参方法
     *
     */
    @Test
    public void Test05(){
        try {
            Object getName = ReflectUtils.invokeMethod(new Student(), "getName");
            System.out.println("name : "+getName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * p6: 测试 通过对象+反射 调用对象的有参方法,并返回调用结果
     *  设置 stu id为 909
     */
    @Test
    public void Test06(){
        try {
            // 1: 参数列表
            Class<?>[] parmas = {int.class};
            Object[] values = {909};
            Student student = ReflectUtils.creteObject(Student.class);
            System.out.println("setId 之前 : "+student);
            Object result = ReflectUtils.invokeMethod(student, "setId",values,parmas);
            System.out.println(result);
            System.out.println("setId 之后 : "+student);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * p7: 测试
     * 使用反射 暴力破解对象属性, 并修改值
     *
     */
    @Test
    public void Test07(){
        try {
            Student student = ReflectUtils.creteObject(Student.class);
            System.out.println("暴力破解 before :"+student);
            ReflectUtils.accessFiled(student,"name","xiugaival");
            System.out.println("暴力破解之后  after :"+student);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 多线程下 使用更加安全
     */
    private static Map<String,Object> map = new ConcurrentHashMap<>(16);
    static {
        map.put("id",520);
        map.put("name","孙娜");
        map.put("love","看美女");
    }

    /**
     * p8: 测试
     * 使用反射 暴力破解对象所有属性, 并修改值
     *
     */
    @Test
    public void Test08(){
        try {

            Student student = ReflectUtils.creteObject(Student.class);
            System.out.println("before-->"+student);
            ReflectUtils.accessAllFileds(student,map);
            System.out.println("after-->"+student);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
